<template>
  <div style="width: 100%" :class="props.border ? 'relation-config' : ''">
    <div class="relation-item">
      <el-select
        v-model="internalRelation.connect"
        placeholder="数据库连接"
        @change="handleConnectChange"
        clearable
        style="width: 30%; margin-right: 10px"
      >
        <el-option
          v-for="item in dbConnections"
          :key="item.value"
          :label="item.label"
          :value="item.value"
        />
      </el-select>

      <el-select
        v-model="internalRelation.relative_name"
        placeholder="关联表"
        filterable
        clearable
        @change="handleTableChange"
        style="width: 30%; margin-right: 10px"
      >
        <el-option
          v-for="item in tables"
          :key="item.value"
          :label="item.label"
          :value="item.value"
        />
      </el-select>

      <el-select
        v-model="internalRelation.field"
        clearable
        placeholder="字段"
        style="width: 30%; margin-right: 10px"
      >
        <el-option
          v-for="column in columns"
          :key="column.value"
          :label="column.label"
          :value="column.value"
        />
      </el-select>

      <el-button @click="clearRelation">清空配置</el-button>
    </div>
  </div>
</template>

<script setup>
/**
 * 这是一个用于定义表与表之间连接的组件
 */
import ActionAPI from '@/api/admin/dev/action';
import MenuAPI from '@/api/admin/dev/menu';
import { ElMessage } from 'element-plus';
import { ref, watch, onMounted } from 'vue';

const props = defineProps({
  modelValue: {
    type: Object,
    default: () => ({
      connect: '',
      relative_name: '',
      field: '',
    }),
  },
  border: {
    type: Boolean,
    default: false,
  },
});

const emit = defineEmits(['update:modelValue']);

// 内部数据存储，用于避免直接修改 props
const internalRelation = ref({});

// 监听 props.modelValue 变化，并同步到 internalRelation
watch(
  () => props.modelValue,
  (newValue) => {
    // 只有当 newValue 与 internalRelation.value 不同时才更新，避免循环更新
    if (JSON.stringify(newValue) !== JSON.stringify(internalRelation.value)) {
      internalRelation.value = { ...newValue };
    }
  },
  { immediate: true, deep: true },
);

// 监听 internalRelation 变化，并同步到父组件
watch(
  internalRelation,
  (newValue) => {
    // 只有当 newValue 与 props.modelValue 不同时才触发 emit，避免循环更新
    if (JSON.stringify(newValue) !== JSON.stringify(props.modelValue)) {
      emit('update:modelValue', newValue);
    }
  },
  { deep: true },
);

const dbConnections = ref([]); // 数据库连接列表
const tables = ref([]); // 表列表
const columns = ref([]); // 列列表

// 清空配置
const clearRelation = () => {
  internalRelation.value = {
    connect: '',
    relative_name: '',
    field: '',
  };
  tables.value = [];
  columns.value = [];
};

// 加载数据库连接
const loadDbConnection = async () => {
  try {
    const { data } = await MenuAPI.getConnects();
    dbConnections.value = data;
    return data;
  } catch (err) {
    console.error('loadDbConnection', err);
    ElMessage.error(err.message);
    throw err;
  }
};

// 数据库连接变化时加载表列表
const handleConnectChange = async () => {
  const conn = internalRelation.value?.connect;
  if (conn) {
    try {
      const { data } = await ActionAPI.getRelationTabls({ conn });
      tables.value = data;
    } catch (err) {
      console.error('handleConnectChange', err);
      tables.value = [];
    }
  } else {
    tables.value = [];
  }
  internalRelation.value.relative_name = '';
  internalRelation.value.field = '';
  columns.value = [];
};

// 表名变化时加载字段列表
const handleTableChange = async () => {
  const conn = internalRelation.value?.connect;
  const table = internalRelation.value?.relative_name;
  if (conn && table) {
    try {
      const { data } = await ActionAPI.getRelationFields({ conn, table });
      columns.value = data;
    } catch (err) {
      console.error('handleTableChange', err);
      columns.value = [];
    }
  } else {
    columns.value = [];
  }
  internalRelation.value.field = '';
};

// 组件挂载时自动加载数据库连接
onMounted(() => {
  loadDbConnection();
});
</script>

<style scoped>
.relation-config {
  border: 1px solid #ebeef5;
  padding: 15px;
  border-radius: 4px;
}

.relation-item {
  display: flex;
  align-items: center;
  margin-bottom: 10px;
}
</style>
